import { normalize } from "node:path";

/**
 * 是否是mac
 */
export const isMac = process.platform === "darwin";

/**
 * 随机UUID
 */
export const generateUUID = (): string => {
  let d = new Date().getTime();
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
    const r = (d + Math.random() * 16) % 16 | 0;
    d = Math.floor(d / 16);
    return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
  });
};

/**
 * 文件大小转换
 * @param bytes
 */
export const bytesToSize = (bytes: number) => {
  const sizes = ["B", "KB", "MB", "GB", "TB"];
  if (bytes === 0) return "0 B";
  const i = Math.floor(Math.log(bytes) / Math.log(1024));
  return `${(bytes / Math.pow(1024, i)).toFixed(2)} ${sizes[i]}`;
};

/**
 * 转换成linux路径
 * @param windowPath
 */
export const toLinuxPath = (windowPath: string) => {
  const path = normalize(windowPath);
  // 去除驱动器字母（如果存在）
  let linuxPath = path.replace(/^[A-Za-z]:\\/, "/");
  // 将所有反斜杠替换为正斜杠
  linuxPath = linuxPath.replace(/\\/g, "/");
  return linuxPath.replace(/\/$/, "");
};

/**
 * 转换成windows路径
 * @param unixPath
 */
export function toWindowPath(unixPath: string) {
  return unixPath.replace(/\//g, "\\");
}

/**
 * Set去重
 * @param arr
 */
export const uniqueSet = (arr: TypedAny[]) => {
  return Array.from(new Set(arr.map((v) => JSON.stringify(v)))).map((v) =>
    JSON.parse(v)
  );
  // return arr.filter((item, index, arr) => arr.indexOf(item) === index)
};

/**
 * 过滤树节点
 * @param arg
 * @param predicate
 */
export const filterTree = <T>(
  arg: T[],
  predicate: (value: T) => boolean
): T[] => {
  const list = arg.filter(predicate);
  list.forEach((v) => {
    // @ts-ignore
    if (v.children) v.children = filterTree(v.children, predicate);
  });
  return list;
};

/**
 * 查找树节点
 * @param arg
 * @param predicate
 */
export const findTree = <T>(
  arg: T[],
  predicate: (value: T) => boolean
): T | undefined => {
  let result: T | undefined;
  for (let i = 0; i < arg.length; i++) {
    const item = arg[i];
    // @ts-ignore
    const children = item.children || [];
    if (predicate(item)) {
      result = item;
      return result;
    } else if (children && children.length) {
      result = findTree(children, predicate);
      if (result) return result;
    }
  }
  return result;
};

/**
 * 遍历树节点
 * @param arg
 * @param predicate
 */
export const eachTree = <T>(arg: T[], predicate: (value: T) => unknown) => {
  for (let i = 0; i < arg.length; i++) {
    const item = arg[i];
    // @ts-ignore
    const children = item.children || [];
    if (children && children.length) {
      eachTree(children, predicate);
    } else {
      predicate(item);
    }
  }
};

/**
 * 多久以前
 * @param time 订单时间（日期格式或者时间戳）
 * @param num 返回几个时间单位，如：1周(num=1)，1周2天(num=2),1周2天1小时(num=3)
 */
export function toFormatTime(time: string | number | Date, num = 1) {
  const timeArr = [
    365 * 24 * 60 * 60 * 1000,
    30 * 24 * 60 * 60 * 1000,
    7 * 24 * 60 * 60 * 1000,
    24 * 60 * 60 * 1000,
    60 * 60 * 1000,
    60 * 1000,
    1000,
  ];
  const unit = ["年", "个月", "周", "天", "小时", "分钟", "秒钟"];
  let timeDiff = Date.now() - new Date(time).getTime();
  if (timeDiff <= 10) return "刚刚";
  const tip = [];
  for (let i = 0; i < timeArr.length; i++) {
    if (timeDiff < timeArr[i]) continue;

    const temp = Math.floor(timeDiff / timeArr[i]);
    timeDiff = timeDiff % timeArr[i];

    if (temp > 0) {
      tip.push(temp + unit[i]);
    }

    if (tip.length >= num) break;
  }
  return (tip.join("") || "1秒") + "前";
}

/**
 * 获取某个字符串后面的字符串
 * @param str
 * @param key
 */
export const getStringAfter = (str: string, key?: string) => {
  // 使用split分割字符串，并在`.`处分割
  const parts = str.split(key || ".");
  // 返回数组中最后一个元素，即`.`后面的所有内容
  return parts.pop();
};

/**
 * 刷新时间
 */
export function refreshFormatTime(list: (WebType | RunType)[]) {
  eachTree(list, (v) => {
    if (v.time) v.time_string = toFormatTime(v.time);
  });
}

/**
 * @description 随机数（闭区间）
 * @param num
 */
export const randomNum = (num: number) => Math.floor(Math.random() * (num + 1));

/**
 * 快速获取对象的值
 * @param obj
 * @param path
 * @param defaultValue
 */
export const getObjectValue = (
  obj: TypedAny,
  path: string | (string | number)[],
  defaultValue?: string
): any => {
  let result = obj;
  if (!path) {
    return result;
  }
  const pathArray = Array.isArray(path) ? path : path.split(".");

  for (let i = 0; i < pathArray.length; i++) {
    let currentPath = pathArray[i];
    if (result === null || result === undefined) {
      return defaultValue;
    }
    result = result[currentPath];
  }
  return result === undefined ? defaultValue : result;
};

/**
 * 时间范围内
 * @param now 毫秒
 * @param minutes 分钟 默认3个小时
 */
export const isNow = (now: number, minutes: number = 180) => {
  const diff = Date.now() - now;
  const current = diff / 1000 / 60;
  return current < minutes;
};

/**
 * 时间范围内的颜色
 * @param now 毫秒
 */
export const isNowColorClass = (now: number) => {
  if (isNow(now, 2 * 60)) {
    return "color-danger";
  } else if (isNow(now, 5 * 60)) {
    return "color-primary";
  } else {
    return "color-placeholder";
  }
};

/**
 * 有趣的语音
 */
export const playMessages = [
  "哎呀，主人，请不要晃了，有点晕。",
  "你非要这样，我也没有办法。",
  "如果这样，能让主人感到开心，那就晃吧。",
  "好晕啊，能不能不要晃我了。",
  "我有一头小毛驴，我从来都不骑。",
  "为什么鱼儿会游泳？因为它们觉得自己太湿了，需要擦干一下。",
  "如果蚊子不吸血，改行抽脂肪，那它会是多么可爱的小生物啊！",
  "为什么鱼喜欢游泳？因为他们不会开车啊！",
  "为什么鱼会游泳？因为他们有游泳衣和游泳镜，还有游泳圈。",
  "为什么鱼会游泳？因为它们有游泳圈啊！",
  "这世界上最美好的事情，莫过于吃肉。从来不会背叛，从来不会欺骗，吃一斤，长一斤，永远真诚相待。",
];

/**
 * 语录合集
 */
export const quotations = [
  {
    label: "笑话",
    value: "https://api.vvhan.com/api/text/joke?type=json",
    props: ["content"],
  },
  {
    label: "海王语录",
    value: "https://api.vvhan.com/api/text/sexy?type=json",
    props: ["content"],
  },
  {
    label: "情话语录",
    value: "https://api.vvhan.com/api/text/love?type=json",
    props: ["content"],
  },
  { label: "每天新闻60秒", value: "https://api.vvhan.com/api/60s" },
];

/**
 * 秒转时分秒
 * @param seconds
 */
export const formatTrackTime = (seconds: number) => {
  const minutes = Math.floor((seconds % 3600) / 60);
  const remainingSeconds = Math.floor(seconds % 60);
  const m = minutes.toString().padStart(2, "0");
  const s = remainingSeconds.toString().padStart(2, "0");
  return `${m}:${s}`;
};
